package com.kantboot.functional.pay.wechat.service.impl;

import com.kantboot.functional.pay.order.emit.PayEmit;
import com.kantboot.functional.pay.order.module.entity.FunctionalPayOrder;
import com.kantboot.functional.pay.order.service.IFunctionalPayOrderService;
import com.kantboot.functional.pay.wechat.module.entity.PayWechatPayParam;
import com.kantboot.functional.pay.wechat.service.IPayWechatService;
import com.kantboot.functional.pay.wechat.util.WechatOrderByOutTradeNoParam;
import com.kantboot.functional.pay.wechat.util.WechatOrderByOutTradeNoResult;
import com.kantboot.functional.pay.wechat.util.WechatPayResult;
import com.kantboot.functional.third.party.wechat.service.ITpWechatService;
import com.kantboot.system.setting.service.ISysSettingService;
import com.kantboot.util.common.exception.BaseException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class PayWechatServiceImpl implements IPayWechatService {

    @Resource
    private IFunctionalPayOrderService payOrderService;

    @Resource
    private ITpWechatService tpWechatService;

    @Resource
    private ISysSettingService settingService;

    @Resource
    private PayEmit payEmit;



    @Override
    public String getPayPrivateKey() {
        String value = settingService.getValue("wechat", "payPrivateKey");
        if (value == null) {
            throw BaseException.of("payCertKeyIsNull", "支付证书密钥为空");
        }
        // 去除证书头尾
        value = value.replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "");
        value=value.trim();
        return value;
    }

    @Override
    public WechatPayResult getPayResult(Long orderId, String code) {
        String appid = settingService.getValue("wechat", "mpAppid");
        String mchid = settingService.getValue("wechat", "mchid");
        String payNotifyURL = settingService.getValue("wechat", "payNotifyURL");
        String payCertSerialNo = settingService.getValue("wechat","payCertSerialNo");
        log.info("appid: {}, mchid: {}, payCertSerialNo: {}",appid,mchid,payCertSerialNo);
        FunctionalPayOrder byId = payOrderService.getById(orderId);
        PayWechatPayParam wechatPayParamDTO = new PayWechatPayParam();
        wechatPayParamDTO.setAppid(appid);
        wechatPayParamDTO.setMchid(mchid);
        wechatPayParamDTO.setOutTradeNo(orderId+"");
        wechatPayParamDTO.setAmountTotal(byId.getAmount());
        wechatPayParamDTO.setAmountCurrency(byId.getCurrency());
        wechatPayParamDTO.setDescription(byId.getDescription());
        wechatPayParamDTO.setNotifyUrl(payNotifyURL+"/"+orderId);
        // 根据code获取openId
        String openIdByCodeInMp = tpWechatService.getOpenIdByCodeInMp(code);
        wechatPayParamDTO.setPayerOpenid(openIdByCodeInMp);
        return wechatPayParamDTO.createResult(getPayPrivateKey(),payCertSerialNo);
    }

    @Override
    public FunctionalPayOrder handleWechatPay(String orderId) {
        // 查询orderId是否已被处理
        FunctionalPayOrder byId = payOrderService.getById(Long.parseLong(orderId));
        // 如果已被处理，直接返回
        if (byId.getIsStatusProcessed()) {
            return byId;
        }

        // 获取微信支付的商户号
        String mchid = settingService.getValue("wechat", "mchid");
        // 获取微信支付的证书serialNo
        String payCertSerialNo = settingService.getValue("wechat","payCertSerialNo");

        // 根据订单号查询订单
        WechatOrderByOutTradeNoResult result  =
                new WechatOrderByOutTradeNoParam()
                        .setMchid(mchid)
                        .setOutTradeNO(orderId)
                        .toResult(getPayPrivateKey(), payCertSerialNo);


        // 如果是未支付状态，更新为未支付状态
        if("NOTPAY".equals(result.getTradeState())) {
            payOrderService.updateStatusCodeById(Long.parseLong(orderId), FunctionalPayOrder.STATUS_CODE_UNPAID);
        }

        // 如果是支付成功状态，更新为支付成功状态
        if("SUCCESS".equals(result.getTradeState())) {
            payOrderService.updateStatusCodeById(Long.parseLong(orderId), FunctionalPayOrder.STATUS_CODE_PAID);
        }

        FunctionalPayOrder order = payOrderService.getById(Long.parseLong(orderId));
        payEmit.emit(order);
        return order;
    }

}
